第一個差異是 Vue 實例的建立方式
在 v2 大家通過 new Vue
建立根實例,而 v3 改為使用 createApp
import { createApp } from 'vue'
const app = createApp({})
原本 Global API 如 Vue.component 、 Vue.directive 等等的方法,現在改為使用 Instance API,基本上就是把原本在 Vue class 上調用的方法移動到實例化後的物件,例如以下:
import { createApp } from 'vue'
import MyComponent from './MyComponent'
const app = createApp({})
app.component('my-component', MyComponent)
移除 config.productionTip ,因為在大部分的 cli 或 boilerplate 都會自動偵測 env 並做相應的處裡,因此這個選項被認為不再需要。
config.ignoreElements 改為 config.isCustomElement 如下:
// v3 前
Vue.config.ignoredElements = ['my-el', /^ion-/]
// v3 後
const app = Vue.createApp({})
app.config.isCustomElement = tag => tag.startsWith('ion-')
請注意 isCustomElement 只有在板模(template)編譯階段中使用,因此如果使用 runtime-only 的 build,isCustomElement 必須在建構過程(build step)中傳給 @vue/compiler-dom,例如通過 vue-loader 的 compilerOptions。
官方也提到,這個設定將會納入 vue-cli 的頂層設定中,意思就是可以透過 vue.config.js 做設定。
關於插件,就像其他 Global API 一樣,現在必須透過實例:
// before v3
import Vue from 'vue'
Vue.use(VueRouter)
// after v3
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.use(VueRouter)
有的時候應用程式可能會同時使用多個 Vue 根實例,而你有可能有元件想全域共於這些實例,這時官方提供一個簡單有效的策略,使用工廠:
import { createApp } from 'vue'
import Foo from './Foo.vue'
import Bar from './Bar.vue'
import MyBtn from './MyBtn.vue'
// 建立自己的 Vue 工廠
const createMyApp = options => {
const app = createApp(options)
// 加上全域設定
app.component('my-btn', MyBtn)
return app
}
createMyApp(Foo).mount('#foo')
createMyApp(Bar).mount('#bar')
生命週期的部分 3 跟 2 沒多大變化,主要差異就是物件銷毀的名詞從 beforeDestory/destoryed 變為 beforeUnmount/unmounted ,內部的觸發名稱由 Destoryed 換為 Unmounted。